/**
 * @file UP_TIMER.c
 * @author your name (you@domain.com)
 * @brief TIMER定时器驱动
 * @version 0.1
 * @date 2023-05-12
 *
 * @copyright Copyright (c) 2023
 *
 * 依赖timer模块
 *
 */
#include "UP_TIMER.h"
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "UP_test.h"

void configureTimer(uint32_t timer_periph, rcu_periph_enum *rcu_periph, IRQn_Type *irqn)
{

    switch (timer_periph) {
        case TIMER0:
            // TODO: TIMER0
            break;
        case TIMER1:
            *rcu_periph   = RCU_TIMER1;
            *irqn         = TIMER1_IRQn;
            break;
        case TIMER2:
            *rcu_periph   = RCU_TIMER2;
            *irqn         = TIMER2_IRQn;
            break;
        case TIMER3:
            *rcu_periph   = RCU_TIMER3;
            *irqn         = TIMER3_IRQn;
            break;
        case TIMER4:
            *rcu_periph   = RCU_TIMER4;
            *irqn         = TIMER4_IRQn;
            break;
        case TIMER5:
            *rcu_periph   = RCU_TIMER5;
            *irqn         = TIMER5_DAC_IRQn;
            break;
        case TIMER6:
            *rcu_periph   = RCU_TIMER6;
            *irqn         = TIMER6_IRQn;
            break;
        case TIMER8:
            *rcu_periph   = RCU_TIMER8;
            *irqn         = TIMER0_BRK_TIMER8_IRQn;
            break;
        case TIMER7:
            // TODO: TIMER7
            break;
        case TIMER9:
            *rcu_periph   = RCU_TIMER9;
            *irqn         = TIMER0_UP_TIMER9_IRQn;
            break;
        case TIMER10:
            *rcu_periph   = RCU_TIMER10;
            *irqn         = TIMER0_TRG_CMT_TIMER10_IRQn;
            break;
        case TIMER11:
            *rcu_periph   = RCU_TIMER11;
            *irqn         = TIMER7_BRK_TIMER11_IRQn;
            break;
        case TIMER12:
            *rcu_periph   = RCU_TIMER12;
            *irqn         = TIMER7_UP_TIMER12_IRQn;
            break;
        case TIMER13:
            *rcu_periph   = RCU_TIMER13;
            *irqn         = TIMER7_TRG_CMT_TIMER13_IRQn;
            break;
        default:
            return;
    }
}


// // 复制此方法后，一定要把此处的方法注释掉
// void TIMER_isr_handler(uint8_t timer)
// {
// }
void TIMER_init(uint32_t timer, uint32_t time_ms)
{
    UP_TIMER_PARAMS params = uc_timer_params_default;
    params.prescaler = 24000U;
    params.period_ms = time_ms;
    params.frequency = 0;
    TIMER_init_with_params(timer, params);
}
/**
 * \brief 初始化定时器
 * \param[in] timer 定时器号
 * \param[in] time_ms 定时时间，单位ms
 * \param[out] none
 * \retval none
 *
 * TIMER 1-6,11,12,13: APB1 60MHz
 * TIMER 0,7-10:       APB2 120MHz
 *
 */
void TIMER_init_with_params(uint32_t timer_periph, UP_TIMER_PARAMS params)
{
    rcu_periph_enum rcu_periph;
    IRQn_Type irqn;
    configureTimer(timer_periph, &rcu_periph, &irqn);

    /* 配置中断优先级 */
    nvic_irq_enable(irqn, 3, 2); // 设置中断优先级为 3,2

    /* 
        一个周期的时间T = 1/f, 定时时间time = T * 周期
        设预分频值位prescaler，周期位period
        定时器时间time计算如下，单位s
        time = (prescaler + 1) * (period + 1) / psc_clk

        perscaler为24000时，最低间隔为100us = 0.1ms 计算方法：1000ms / 10000 = 0.1ms
    */
    // 分频系数
    uint32_t prescaler = params.prescaler;
    uint32_t period;    // 周期的计数值
    if (params.frequency > 0){

        period = ((SystemCoreClock / prescaler) / params.frequency);

    }else if (params.period_ms > 0){
        // 计算周期：1000ms * (240000000 / 24000) / 1000 = 10000
        // 意义解释：
        //           (240000000 / 24000) = 10000         即1s内计数10000次
        //           (240000000 / 24000) / 1000 = 10     即1ms内计数10次
        // time_ms * (240000000 / 24000) / 1000 = 10 000 例如：希望延时1000ms则需要用1000ms * 10次 = 10000次
        period = params.period_ms * (SystemCoreClock / prescaler) / 1000;
    }else {
        // 周期和频率同时为0, 不进行初始化
        timer_disable(timer_periph);
        return;
    }

    /* 开启时钟 */
    rcu_periph_clock_enable(rcu_periph); // 开启定时器时钟

    switch (timer_periph) {
        case TIMER1:
        case TIMER2:
        case TIMER3:
        case TIMER4:
        case TIMER5:
        case TIMER6:
        case TIMER11:
        case TIMER12:
        case TIMER13:
            // * TIMER 1-6,11,12,13: APB1 60MHz
            /* CK_TIMERx = 4 x CK_APB1  = 4x60M = 240MHZ */
            rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4); // 配置定时器时钟
            break;
        default:
            // * TIMER 0,7-10: APB2 120MHz
            /* CK_TIMERx = 2 x CK_APB2  = 2x120M = 240MHZ */
            rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL2); // 配置定时器时钟
            break;
    }

    timer_deinit(timer_periph); // 复位定时器
    
    timer_parameter_struct timere_initpara; // 定义定时器结构体
    /* 配置定时器参数 */
    timere_initpara.prescaler        = prescaler - 1;      //  时钟预分频值 0-65535   psc_clk = CK_TIMER / period
    timere_initpara.alignedmode      = TIMER_COUNTER_EDGE; // 边缘对齐
    timere_initpara.counterdirection = TIMER_COUNTER_UP;   // 向上计数
    timere_initpara.period           = period - 1;         // 周期，计数period - 1次，过去了time_ms毫秒
    /* 在输入捕获的时候使用  数字滤波器使用的采样频率之间的分频比例 */
    timere_initpara.clockdivision = TIMER_CKDIV_DIV1; // 分频因子，不分频 1/2/4
                                                      /* 只有高级定时器才有 配置为x，就重复x+1次进入中断 */
    timere_initpara.repetitioncounter = 0;            // 重复计数器 0-255

    timer_init(timer_periph, &timere_initpara); // 初始化定时器
    /* 使能中断 */
    timer_interrupt_enable(timer_periph, TIMER_INT_UP); // 使能更新事件中断
    /* 使能定时器 */
    if(params.disable != 1)
    {
        timer_enable(timer_periph);
    }
}

#if TEST_TYPE == TEST_SPI
void TM1_isr(void){}
// void TM2_isr(void){}
// void TM3_isr(void){}
void TM4_isr(void){}
#elif TEST_TYPE == TEST_TIMER
// void TM1_isr(void){}
// void TM2_isr(void){}
// void TM3_isr(void){}
// void TM4_isr(void){}
#elif TEST_TYPE == TEST_ADC || TEST_TYPE == TEST_DAC
void TM1_isr(void){}
void TM2_isr(void){}
// void TM3_isr(void){}
void TM4_isr(void){}
#else
void TM1_isr(void){}
void TM2_isr(void){}
void TM3_isr(void){}
void TM4_isr(void){}
#endif

void TM5_isr(void){}
void TM6_isr(void){}
void TM8_isr(void){}
void TM9_isr(void){}
void TM10_isr(void){}
void TM11_isr(void){}
void TM12_isr(void){}
void TM13_isr(void){}

void TIMER1_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM1_isr();
    }
}

 void TIMER2_IRQHandler(void)
 {
     /* 这里是定时器中断 */
     if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP) == SET) {
         timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP); // 清除中断标志位
         TM2_isr();
     }
 }

 void TIMER3_IRQHandler(void)
 {
     /* 这里是定时器中断 */
     if (timer_interrupt_flag_get(TIMER3, TIMER_INT_FLAG_UP) == SET) {
         timer_interrupt_flag_clear(TIMER3, TIMER_INT_FLAG_UP); // 清除中断标志位
         TM3_isr();
     }
 }

void TIMER4_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER4, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER4, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM4_isr();
    }
}

void TIMER5_DAC_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER5, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM5_isr();
    }
}

void TIMER6_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER6, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER6, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM6_isr();
    }
}

void TIMER0_BRK_TIMER8_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER8, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER8, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM8_isr();
    }
}

void TIMER0_UP_TIMER9_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER9, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER9, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM9_isr();
    }
}

void TIMER0_TRG_CMT_TIMER10_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER10, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER10, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM10_isr();
    }
}

void TIMER7_BRK_TIMER11_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER11, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER11, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM11_isr();
    }
}

void TIMER7_UP_TIMER12_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER12, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER12, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM12_isr();
    }
}

void TIMER7_TRG_CMT_TIMER13_IRQHandler(void)
{
    /* 这里是定时器中断 */
    if (timer_interrupt_flag_get(TIMER13, TIMER_INT_FLAG_UP) == SET) {
        timer_interrupt_flag_clear(TIMER13, TIMER_INT_FLAG_UP); // 清除中断标志位
        TM13_isr();
    }
}